package Leetcode.动态规划;

/**
 * @Author kirito
 * @Date 2023/11/16 9:50
 * @PackageName:Leetcode.动态规划
 * @ClassName: 最长奇偶子数组
 * @Description:
 * 给你一个下标从 0 开始的整数数组 nums 和一个整数 threshold 。
 *
 * 请你从 nums 的子数组中找出以下标 l 开头、下标 r 结尾 (0 <= l <= r < nums.length) 且满足以下条件的 最长子数组 ：
 *
 * nums[l] % 2 == 0   ==》起始位置为偶数
 * 对于范围 [l, r - 1] 内的所有下标 i ，nums[i] % 2 != nums[i + 1] % 2   ==》   偶奇偶奇    单数索引位置为偶数，双数索引位置为奇数
 * 对于范围 [l, r] 内的所有下标 i ，nums[i] <= threshold       =》范围内最大值不超过的最大值
 * 以整数形式返回满足题目要求的最长子数组的长度。
 *
 * 注意：子数组 是数组中的一个连续非空元素序列。
 *
 *
 *
 * 示例 1：
 *
 * 输入：nums = [3,2,5,4], threshold = 5
 * 输出：3
 * 解释：在这个示例中，我们选择从 l = 1 开始、到 r = 3 结束的子数组 => [2,5,4] ，满足上述条件。
 * 因此，答案就是这个子数组的长度 3 。可以证明 3 是满足题目要求的最大长度。
 * 示例 2：
 *
 * 输入：nums = [1,2], threshold = 2
 * 输出：1
 * 解释：
 * 在这个示例中，我们选择从 l = 1 开始、到 r = 1 结束的子数组 => [2] 。
 * 该子数组满足上述全部条件。可以证明 1 是满足题目要求的最大长度。
 * 示例 3：
 *
 * 输入：nums = [2,3,4,5], threshold = 4
 * 输出：3
 * 解释：
 * 在这个示例中，我们选择从 l = 0 开始、到 r = 2 结束的子数组 => [2,3,4] 。
 * 该子数组满足上述全部条件。
 * 因此，答案就是这个子数组的长度 3 。可以证明 3 是满足题目要求的最大长度。
 * @Version 1.0
 */
public class 最长奇偶子数组 {
    public int longestAlternatingSubarray(int[] nums, int threshold) {
        int res = 0; // 最长交替子数组的长度
        int dp = 0; // 当前交替子数组的长度

        // 从数组的最后一个元素开始向前遍历
        for (int l = nums.length - 1; l >= 0; l--) {
            if (nums[l] > threshold) {
                dp = 0; // 如果当前元素大于阈值，则重置当前交替子数组的长度为0
            } else if (l == nums.length - 1 || nums[l] % 2 != nums[l + 1] % 2) {
                dp++; // 如果当前元素是奇数且前一个元素是偶数，或者当前元素是偶数且前一个元素是奇数，则将当前交替子数组的长度加1
            } else {
                dp = 1; // 否则，当前元素和前一个元素的奇偶性相同，重置当前交替子数组的长度为1
            }

            if (nums[l] % 2 == 0) {
                res = Math.max(res, dp); // 如果当前元素是偶数，则更新最长交替子数组的长度
            }
        }

        return res; // 返回最长交替子数组的长度
    }

    public int longestAlternatingSubarray2(int[] nums, int threshold) {
        int n = nums.length;
        int ans = 0, i = 0;
        while (i < n) {
            if (nums[i] > threshold || nums[i] % 2 != 0) {
                i++; // 直接跳过
                continue;
            }
            int start = i; // 记录这一组的开始位置
            i++; // 开始位置已经满足要求，从下一个位置开始判断
            while (i < n && nums[i] <= threshold && nums[i] % 2 != nums[i - 1] % 2) {
                i++;
            }
            // 从 start 到 i-1 是满足题目要求的子数组
            ans = Math.max(ans, i - start);
        }
        return ans;
    }

}
